/*
* Author: Chris Seguin
*
* This software has been developed under the copyleft
* rules of the GNU General Public License. Please
* consult the GNU General Public License for more
* details about use and distribution of this software.
*/
package org.acm.seguin.refactor.method;
import java.util.Iterator;
import java.util.LinkedList;
import org.acm.seguin.parser.ast.ASTMethodDeclaration;
import org.acm.seguin.parser.ast.SimpleNode;
import org.acm.seguin.refactor.ComplexTransform;
import org.acm.seguin.refactor.RefactoringException;
import org.acm.seguin.summary.TypeDeclSummary;
import org.acm.seguin.summary.TypeSummary;
import org.acm.seguin.summary.query.GetTypeSummary;
/**
* Performs the push down method refactoring
*
*@author Chris Seguin
*/
public class PushDownMethodRefactoring extends InheretenceMethodRefactoring
{
private LinkedList destinations;
private TypeSummary typeSummary;
/**
* Constructor for the PushDownMethodRefactoring object
*/
protected PushDownMethodRefactoring()
{
destinations = new LinkedList();
}
/**
* Gets the description of the refactoring
*
*@return the description
*/
public String getDescription()
{
return "Moves a method " + methodSummary.getName() +
" down into the child classes of " + typeSummary.getName();
}
/**
* Gets the ID attribute of the PushDownMethodRefactoring object
*
*@return The ID value
*/
public int getID()
{
return PUSH_DOWN_METHOD;
}
/**
* Adds a feature to the Child attribute of the PushDownMethodRefactoring
* object
*
*@param type The feature to be added to the Child attribute
*/
public void addChild(TypeSummary type)
{
destinations.add(type);
}
/**
* This specifies the preconditions for applying the refactoring
*
*@exception RefactoringException Description of Exception
*/
protected void preconditions() throws RefactoringException
{
if (methodSummary == null)
{
throw new RefactoringException("No method specified");
}
typeSummary = (TypeSummary) methodSummary.getParent();
Iterator iter = destinations.iterator();
while (iter.hasNext())
{
TypeSummary next = (TypeSummary) iter.next();
TypeDeclSummary parent = next.getParentClass();
TypeSummary parentSummary = GetTypeSummary.query(parent);
if (parentSummary != typeSummary)
{
throw new RefactoringException(next.getName() + " is not a subclass of " + typeSummary.getName());
}
checkDestination(next);
}
}
/**
* Moves the method to the parent class
*/
protected void transform()
{
RemoveMethodTransform rft = new RemoveMethodTransform(methodSummary);
ComplexTransform transform = getComplexTransform();
removeMethod(typeSummary, transform, rft);
// Update the method declaration to have the proper permissions
SimpleNode methodDecl = rft.getMethodDeclaration();
if (methodDecl == null)
{
return;
}
ASTMethodDeclaration decl = updateMethod(methodDecl);
Iterator iter = destinations.iterator();
while (iter.hasNext())
{
TypeSummary next = (TypeSummary) iter.next();
addMethodToDest(transform, rft, methodDecl, next);
}
}
/**
* Description of the Method
*
*@param source Description of Parameter
*@param transform Description of Parameter
*@param rft Description of Parameter
*/
protected void removeMethod(TypeSummary source, ComplexTransform transform, RemoveMethodTransform rft)
{
transform.add(new AddAbstractMethod(methodSummary));
super.removeMethod(source, transform, rft);
}
}